package com.ds.home.service.impl;

import com.ds.config.ErrorListResultModel;
import com.ds.config.ErrorResultModel;
import com.ds.config.ListResultModel;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.esb.config.EsbBeanAnnotation;
import com.ds.home.engine.AppEngine;
import com.ds.iot.*;
import com.ds.iot.api.inner.IotService;
import com.ds.iot.enums.DeviceDataTypeKey;
import com.ds.iot.enums.DeviceStatus;
import com.ds.iot.enums.ZNodeZType;

import java.util.ArrayList;
import java.util.List;

@EsbBeanAnnotation(id = "IotService", name = "IotService", expressionArr = "IotServiceImpl()", desc = "IotService")

public class IotServiceImpl implements IotService {

    private final AppEngine appEngine;

    public IotServiceImpl() {

        this.appEngine = AppEngine.getEngine(JDSActionContext.getActionContext().getSystemCode());
    }

    @Override
    public ResultModel<Device> getDeviceById(String deviceId) {

        ResultModel<Device> result = new ResultModel<Device>();
        try {
            Device device = appEngine.getDeviceById(deviceId);
            result.setData(device);
        } catch (Exception e) {
            result = new ErrorResultModel();
           // ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;

    }

    @Override
    public ResultModel<Device> getDeviceByIeee(String deviceieee) {

        ResultModel<Device> result = new ResultModel<Device>();
        try {
            Device device = appEngine.getDeviceBySerialno(deviceieee);
            result.setData(device);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<DeviceEndPoint> getEndPointById(String endPointId) {
        ResultModel<DeviceEndPoint> result = new ResultModel<DeviceEndPoint>();
        try {
            DeviceEndPoint endPoint = appEngine.getEndPoint(endPointId);
            result.setData(endPoint);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<DeviceEndPoint> getEndPointByIeee(String epieee) {
        ResultModel<DeviceEndPoint> result = new ResultModel<DeviceEndPoint>();
        try {
            DeviceEndPoint endPoint = appEngine.getEndPointSerialno(epieee);
            result.setData(endPoint);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<ZNode> getZNodeById(String znodeId) {
        ResultModel<ZNode> result = new ResultModel<ZNode>();
        try {
            ZNode zNode = appEngine.getZNodeById(znodeId);
            result.setData(zNode);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ListResultModel<List<Sensortype>> getSensorsType() {
        ListResultModel<List<Sensortype>> result = new ListResultModel<List<Sensortype>>();
        try {
            List<Sensortype> sensortypes = appEngine.getAllSensorType();
            result.setData(sensortypes);
        } catch (HomeException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<ZNode> createRootZNode(String endPointId, String placeid, String personId, ZNodeZType type) {
        ResultModel<ZNode> result = new ResultModel<ZNode>();
        try {
            ZNode zNode = appEngine.createRootZNode(endPointId, placeid, personId, type);
            result.setData(zNode);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<ZNode> createChildZNode(String parentId, String endPointId) {
        ResultModel<ZNode> result = new ResultModel<ZNode>();
        try {
            ZNode zNode = appEngine.createChildZNode(parentId, endPointId);
            result.setData(zNode);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Device> createDevice(String serialno, String serialno1, Integer deviceType, String factoryName, String gwDeviceId) {
        ResultModel<Device> result = new ResultModel<Device>();
        try {
            Device device = appEngine.createDevice(serialno, serialno1, deviceType, factoryName, gwDeviceId);
            result.setData(device);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> removeChildDevice(String bindingAccount, String deviceid) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.removeChildDevice(bindingAccount, deviceid);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> updateNodeStatus(String znodeid, DeviceStatus status) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.updateNodeStatus(znodeid, status);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> deleteNode(String nodeId) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.deleteZNode(nodeId);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> updateZNode(ZNode znode) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.updateZNode(znode, true);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> updateDevice(Device device) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.updateDevice(device, true);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> updateEndPoint(DeviceEndPoint endPoint) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.updateEndPoint(endPoint, true);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> deleteDevice(String deviceid) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.deleteDevice(deviceid);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Boolean> clearDevices(String[] deviceids) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        for (String deviceid : deviceids) {
            try {
                appEngine.clearDevice(deviceid);
            } catch (HomeException e) {
                e.printStackTrace();

            }
        }
        return result;
    }

    @Override
    public ResultModel<Alarm> getAlarmById(String alarmid) {
        ResultModel<Alarm> result = new ResultModel<Alarm>();
        try {
            Alarm alarm = appEngine.getAlarmById(alarmid);
            result.setData(alarm);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }


    @Override
    public ResultModel<Sensortype> updateSensorType(Sensortype sensortype) {

        ResultModel<Sensortype> result = new ResultModel<Sensortype>();
        try {
            appEngine.updateSensorType(sensortype);
            sensortype = appEngine.getSensorTypesByNo(sensortype.getType());
            result.setData(sensortype);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;


    }

    @Override
    public ResultModel<Boolean> deleteSensorType(Integer typeno) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.deleteSensorType(typeno);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;

    }

    @Override
    public ListResultModel<List<String>> getSensorIdsByBindAccount(String account) {
        ListResultModel<List<String>> result = new ListResultModel<List<String>>();
        List<String> ids = new ArrayList<String>();
        try {
            List<ZNode> znodes = appEngine.findZNodesByCreateId(account, null);
            for (ZNode znode : znodes) {
                ids.add(znode.getZnodeid());
            }
            result.setData(ids);
        } catch (HomeException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<Device> createRootDevice(String deviceId, String serialno, String macno, String systemCode, String currVersion) {
        ResultModel<Device> result = new ResultModel<Device>();
        try {
            Device device = appEngine.createRootDevice(deviceId, serialno, macno, systemCode, currVersion);
            result.setData(device);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @Override
    public ResultModel<DeviceEndPoint> createEndPoint(String sensorieee, String epieee, String ep, Integer sensorType, String name) {

        ResultModel<DeviceEndPoint> result = new ResultModel<DeviceEndPoint>();
        try {
            DeviceEndPoint endPoint = appEngine.registerEndPoint(sensorieee, epieee, ep, sensorType, name);
            result.setData(endPoint);
        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;

    }

    @Override
    public ResultModel<Boolean> updateCurrvalue(String endPointId, String type, String currvalue) {

        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {
            appEngine.getEndPoint(endPointId).updateCurrvalue(DeviceDataTypeKey.fromType(type), currvalue);

        } catch (HomeException e) {
            result = new ErrorResultModel();
            ((ErrorResultModel) result).setErrcode(e.getErrorCode());
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;

    }
}
